package com.xtedu.examproject.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xtedu.examproject.entity.Course;
import com.xtedu.examproject.entity.Examination;
import com.xtedu.examproject.entity.User;
import com.xtedu.examproject.entity.paperTemplates;
import com.xtedu.examproject.service.CourseService;
import com.xtedu.examproject.service.ExaminationService;
import com.xtedu.examproject.service.PaperTemplatesService;
import com.xtedu.examproject.util.RedisUtil;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/*
 * Author: xzy
 * Date: 2025/10/14
 * Last Modified by: xzy
 * Last Modified date: 2025/10/14
 * Description: 管理考试信息的Servlet，支持从数据库获取考试信息并使用Redis进行缓存
 */
@WebServlet("/teaexammanage/*")
public class ExamServlet extends HttpServlet {
    private ExaminationService examinationService;
    private CourseService courseService = new CourseService();
    private PaperTemplatesService paperTemplatesService = new PaperTemplatesService();

    @Override
    public void init() throws ServletException {
        examinationService = new ExaminationService();
        courseService = new CourseService();
        paperTemplatesService = new PaperTemplatesService();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        // 获取路径信息
        String pathInfo = req.getPathInfo();
        // 处理路径信息
        String path = (pathInfo == null || pathInfo.equals("/") || pathInfo.isEmpty()) ? "/" : pathInfo;
        try {
            switch (path) {
                case "/edit":
                    getExaminationById(req, resp);
                    break;
                default:
                    showExaminationManage(req, resp);
                    break;
            }
        } catch (Exception e) {
            throw new ServletException("处理请求失败", e);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        // 获取路径信息
        String pathInfo = req.getPathInfo();

        try {
            if (pathInfo == null || pathInfo.equals("/") || pathInfo.equals("")) {
                showExaminationManage(req, resp);
            } else {
                showExaminationManage(req, resp);
            }
        } catch (Exception e) {
            throw new ServletException("处理请求失败", e);
        }
    }

    public void showExaminationManage(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        List<Examination> mergeExaminations = new ArrayList<>();
        List<Integer> courseIds;
        List<Course> courses;
        List<paperTemplates> paperTemplates;
        courses = courseService.findAllCourseIdAndName();
        paperTemplates = paperTemplatesService.findAll();

        // 尝试从Redis中获取考试信息
        try {
            //获取课程id
            courseIds = RedisUtil.getObject("courseIds", new TypeReference<>() {
            });
            if(courseIds==null){
                try {
                    courseIds=courseService.findAllCourse().stream().map(Course::getId).toList();
                    RedisUtil.setObject("courseIds", courseIds, 60*60*24);
                } catch (Exception e) {
                    //记录日志
                    throw new RuntimeException(e);
                }
            }
            for(Integer courseId:courseIds){
                List<Examination> examinations;
                // 如果Redis中没有或者获取失败，则从数据库获取
                 examinations=RedisUtil.getObject("exam:"+courseId,new TypeReference<List<Examination>>() {});
                 if (examinations==null){
                     try {
                         examinations=examinationService.getExaminationByCourseId(courseId);
                         RedisUtil.setObject("exam:"+courseId, examinations, 60*60*24);
                     } catch (Exception e) {
                         //记录日志
                         throw new RuntimeException(e);
                     }
                 }
                 mergeExaminations.addAll(examinations);

            }
        } catch (Exception e) {
            System.out.println("从Redis获取考试信息失败: " + e.getMessage());
        }
        // 传递数据并修改JSP页面
        req.setAttribute("examinations", mergeExaminations);
        req.setAttribute("courses", courses);
        req.setAttribute("paperTemplates", paperTemplates);
        HttpSession session = req.getSession();
        User user =RedisUtil.getObject("session:" + session.getId(), User.class);
        req.setAttribute("userName", user.getName());
        req.getRequestDispatcher("/WEB-INF/views/examManage.jsp").forward(req, resp);
    }

    /**
     *根据考试id获取考试信息
     */
    public void getExaminationById(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");
        int examId = Integer.parseInt(req.getParameter("examId"));
        Examination examination = examinationService.getExaminationById(examId);
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(examination);
        resp.getWriter().write(json);

    }

    @Override
    public void destroy() {
        super.destroy();
    }
}
